
package com.huawei.jenkins.codeCheck;

import com.google.common.base.Preconditions;
import com.huaweicloud.sdk.codeartscheck.v2.CodeArtsCheckClient;
import com.huaweicloud.sdk.codeartscheck.v2.model.*;
import com.huaweicloud.sdk.codeartscheck.v2.region.CodeArtsCheckRegion;
import com.huaweicloud.sdk.core.auth.BasicCredentials;
import com.huaweicloud.sdk.core.auth.ICredential;
import com.huaweicloud.sdk.core.exception.ConnectionException;
import com.huaweicloud.sdk.core.exception.RequestTimeoutException;
import com.huaweicloud.sdk.core.exception.ServiceResponseException;
import com.huaweicloud.sdk.smn.v2.SmnClient;
import com.huaweicloud.sdk.smn.v2.model.PublishMessageRequest;
import com.huaweicloud.sdk.smn.v2.model.PublishMessageRequestBody;
import com.huaweicloud.sdk.smn.v2.region.SmnRegion;
import hudson.model.TaskListener;
import org.apache.commons.lang.StringUtils;

import java.io.IOException;
import java.io.Serializable;
import java.util.Arrays;
import java.util.List;

public class codeCheckService implements Serializable {
    private static final long serialVersionUID = 1;

    /**
     * 新建检查任务
     *
     * @param listener    日志
     * @param customInput 用户输入
     * @throws IOException          异常
     * @throws InterruptedException 异常
     */
    public static String CreateTask(CodeArtsCheckClient client, TaskListener listener, CustomInput customInput) {


        CreateTaskRequest request = new CreateTaskRequest();
        request.withProjectId(customInput.getProject_id());
        CreateTaskRequestV2 body = new CreateTaskRequestV2();
        List<String> language = Arrays.asList(customInput.getLanguage().split(","));
        body.withLanguage(language);
        body.withGitBranch(customInput.getGitBranch());
        body.withGitUrl(customInput.getGitUrl());
        body.withAccessToken(customInput.getPassWord());
        body.withUsername(customInput.getUserName());
        request.withBody(body);
        String taskId = "";
        try {
            CreateTaskResponse response = client.createTask(request);
            taskId = response.getTaskId();
            listener.getLogger().println("taskId=" + taskId);
        } catch (ConnectionException e) {
            e.printStackTrace();
        } catch (RequestTimeoutException e) {
            e.printStackTrace();
        } catch (ServiceResponseException e) {
            e.printStackTrace();
            listener.getLogger().println("创建任务错误信息：" + e.getErrorMsg());
        }
        return taskId;
    }


    /**
     * 执行检查任务
     *
     * @param listener    日志
     * @param customInput 用户输入
     * @throws IOException          异常
     * @throws InterruptedException 异常
     */
    public static String runTask(TaskListener listener, CustomInput customInput) {
        inputValidate(customInput);

        ICredential auth = new BasicCredentials()
                .withAk(customInput.getAk())
                .withSk(customInput.getSk());

        CodeArtsCheckClient client = CodeArtsCheckClient.newBuilder()
                .withCredential(auth)
                .withRegion(CodeArtsCheckRegion.valueOf(customInput.getRegion()))
                .build();


        //没有taskId新建检查任务,有就查看当前任务是否在执行，如果任务正在执行，直接返回失败
        if (StringUtils.isBlank(customInput.getTask_id())) {
            String taskId = CreateTask(client, listener, customInput);
            customInput.setTask_id(taskId);
        } else {
            Boolean status = ShowProgressDetail(client, customInput.getTask_id(), listener);
            Preconditions.checkArgument(!status, "任务正在执行中,请稍后在试");
        }


        RunTaskRequest request = new RunTaskRequest();
        request.withTaskId(customInput.getTask_id());
        RunRequestV2 body = new RunRequestV2();
        request.withBody(body);
        String message = "";
        try {
            RunTaskResponse response = client.runTask(request);
            if (response.getHttpStatusCode() == 200) {
                listener.getLogger().println("执行检查任务成功");
                Boolean status = true;
                while (status) {
                    status = ShowProgressDetail(client, customInput.getTask_id(), listener);
                    try {
                        Thread.currentThread().sleep(30000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                listener.getLogger().println("检查任务执行完成！！！！");

                message = ShowTaskDetail(client, customInput, listener);
            } else if (response.getHttpStatusCode() == 400) {
                listener.getLogger().println("网络繁忙，请稍后再试");
            } else {
                listener.getLogger().println("认证信息过期");
            }
        } catch (ConnectionException e) {
            e.printStackTrace();
        } catch (RequestTimeoutException e) {
            e.printStackTrace();
        } catch (ServiceResponseException e) {
            e.printStackTrace();
            listener.getLogger().println("执行检查任务错误信息：" + e.getErrorMsg());
            message = e.getErrorMsg();
        }
        return message;
    }


    /**
     * 查看任务状态
     *
     * @param listener 日志
     * @param taskId   任务Id
     * @throws IOException          异常
     * @throws InterruptedException 异常
     */
    public static Boolean ShowProgressDetail(CodeArtsCheckClient client, String taskId, TaskListener listener) {
        ShowProgressDetailRequest request = new ShowProgressDetailRequest();
        request.withTaskId(taskId);
        ShowProgressDetailResponse response = null;
        try {
            response = client.showProgressDetail(request);
            if (StringUtils.isNotBlank(response.getProgress().getRatio())) {
                listener.getLogger().println("任务进度：" + response.getProgress().getRatio());
            }
        } catch (ConnectionException e) {
            e.printStackTrace();
        } catch (RequestTimeoutException e) {
            e.printStackTrace();
        } catch (ServiceResponseException e) {
            e.printStackTrace();
            listener.getLogger().println("查看任务状态错误信息：" + e.getErrorMsg());
        }

        if (response.getTaskStatus() == 0) {
            return true;
        } else {
            return false;
        }

    }


    /**
     * 查看任务结果
     *
     * @param listener    日志
     * @param customInput 用户输入
     * @throws IOException          异常
     * @throws InterruptedException 异常
     */
    public static String ShowTaskDetail(CodeArtsCheckClient client, CustomInput customInput, TaskListener listener) {
        String message = "";
        ShowTaskDetailRequest request = new ShowTaskDetailRequest();
        request.withTaskId(customInput.getTask_id());
        try {
            ShowTaskDetailResponse info = client.showTaskDetail(request);
            listener.getLogger().println("致命问题数：" + info.getCriticalCount());
            listener.getLogger().println("严重问题数：" + info.getMajorCount());
            listener.getLogger().println("常规问题数：" + info.getMinorCount());
            listener.getLogger().println("提示问题数：" + info.getSuggestionCount());
            if (info.getIsAccess().equals("0")) {
                message = "门禁质量通过";
                //删除检查任务，如果任务在执行中,则不删除
                boolean status = ShowProgressDetail(client, customInput.getTask_id(), listener);
                if (!status && customInput.getDeleteTask().equals("true")) {
                    deleteTask(customInput, listener);
                }
            } else {
                message = "门禁质量不通过";
                String url = "https://console.huaweicloud.com/devcloud/?region=" + customInput.getRegion() + "#/codecheck/list";
                listener.getLogger().println("关于具体详情，可前往：" + url + "\n查看");
                // 发送钉钉微信通知
                if (StringUtils.isNotBlank(customInput.getTopicUrn())) {
                    // 发送钉钉微信通知
                    publishMessage(customInput, info, listener);
                }
            }
            listener.getLogger().println(message);

        } catch (ConnectionException e) {
            e.printStackTrace();
        } catch (RequestTimeoutException e) {
            e.printStackTrace();
        } catch (ServiceResponseException e) {
            e.printStackTrace();
            listener.getLogger().println("查看任务结果错误信息：" + e.getErrorMsg());
        }
        return message;
    }


    /**
     * 删除任务
     *
     * @param listener    日志
     * @param customInput 用户输入
     * @throws IOException          异常
     * @throws InterruptedException 异常
     */
    public static void deleteTask(CustomInput customInput, TaskListener listener) {

        ICredential auth = new BasicCredentials()
                .withAk(customInput.getAk())
                .withSk(customInput.getSk());

        CodeArtsCheckClient client = CodeArtsCheckClient.newBuilder()
                .withCredential(auth)
                .withRegion(CodeArtsCheckRegion.valueOf(customInput.getRegion()))
                .build();
        DeleteTaskRequest request = new DeleteTaskRequest();
        request.withTaskId(customInput.getTask_id());
        try {
            client.deleteTask(request);
        } catch (ConnectionException e) {
            e.printStackTrace();
        } catch (RequestTimeoutException e) {
            e.printStackTrace();
        } catch (ServiceResponseException e) {
            e.printStackTrace();
            listener.getLogger().println("删除任务错误信息：" + e.getErrorMsg());
        }
    }


    /**
     * SMN发送消息通知
     *
     * @param listener    日志
     * @param customInput 用户输入
     * @throws IOException          异常
     * @throws InterruptedException 异常
     */
    public static void publishMessage(CustomInput customInput, ShowTaskDetailResponse info, TaskListener listener) {
        ICredential auth = new BasicCredentials().withAk(customInput.getAk()).withSk(customInput.getSk());

        SmnClient client = SmnClient.newBuilder().withCredential(auth)
                .withRegion(SmnRegion.valueOf(customInput.getRegion())).build();
        PublishMessageRequest request = new PublishMessageRequest();
        request.withTopicUrn(customInput.getTopicUrn());
        PublishMessageRequestBody body = new PublishMessageRequestBody();
        String url = "https://console.huaweicloud.com/devcloud/?region=" + customInput.getRegion() + "#/codecheck/list";
        String message = "尊敬的华为云用户，您好：\n本次执行代码检查的结果：";
        message += "\n致命问题数：" + info.getCriticalCount();
        message += "\n严重问题数：" + info.getMajorCount();
        message += "\n常规问题数：" + info.getMinorCount();
        message += "\n提示问题数：" + info.getSuggestionCount();
        if (info.getIsAccess().equals("0")) {
            message += "\n门禁质量通过";
        } else {
            message += "\n门禁质量不通过";
        }
        message += "\n关于具体详情，可前往：" + url + "\n查看";
        body.withMessage(message);
        request.withBody(body);
        try {
            client.publishMessage(request);
        } catch (ConnectionException e) {
            e.printStackTrace();
        } catch (RequestTimeoutException e) {
            e.printStackTrace();
        } catch (ServiceResponseException e) {
            e.printStackTrace();
            listener.getLogger().println("SMN服务消息发生失败，错误信息：" + e.getErrorMsg());
        }
    }


    /**
     * 参数校验
     *
     * @param customInput 用户输入
     * @throws IOException          异常
     * @throws InterruptedException 异常
     */
    private static void inputValidate(CustomInput customInput) {
        final String ak = customInput.getAk();
        final String sk = customInput.getSk();
        final String region = customInput.getRegion();
        final String projectId = customInput.getProject_id();
        final String deleteTask = customInput.getDeleteTask();
        final String taskId = customInput.getTask_id();
        Preconditions.checkArgument(StringUtils.isNotBlank(projectId), "projectId id can not be blank");
        Preconditions.checkArgument(StringUtils.isNotBlank(region), "region can not be blank");
        Preconditions.checkArgument(StringUtils.isNotBlank(deleteTask), "deleteTask can not be blank");
        Preconditions.checkArgument(StringUtils.isNotBlank(ak) && StringUtils.isNotBlank(sk),
                "Ak, Sk can not be blank");
        if (StringUtils.isBlank(taskId)) {
            final String language = customInput.getLanguage();
            final String gitBranch = customInput.getGitBranch();
            final String gitUrl = customInput.getGitUrl();
            Preconditions.checkArgument(StringUtils.isNotBlank(language), "language can not be blank");
            Preconditions.checkArgument(StringUtils.isNotBlank(gitBranch), "git branch can not be blank");
            Preconditions.checkArgument(StringUtils.isNotBlank(gitUrl), "git Url can not be blank");
        }
    }
}
